package cn.gdchent.springbootsecurity.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtil {

    public static File zip(String path, String saveDir, String zipName, boolean keepDirStructure) {
        File target = null;
        File source = new File(path);
        if (source.exists()) {
            target = new File(new File(saveDir), zipName);
            if (target.exists()) {
                if (!target.delete()) {
                    throw new RuntimeException("delete file failed: " + target.getName());
                }
            }
            FileOutputStream fos;
            ZipOutputStream zos = null;
            try {
                fos = new FileOutputStream(target);
                zos = new ZipOutputStream(new BufferedOutputStream(fos));
                compress(source, zos, source.getName(), keepDirStructure);
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                FileUtil.deleteDir(path);
                ClosableUtil.close(zos);
            }
        }
        return target;
    }

    private static void compress(File src, ZipOutputStream zos, String name, boolean keepDirStructure) throws Exception {
        byte[] buffer = new byte[1024];
        if (src.isFile()) {
            zos.putNextEntry(new ZipEntry(name));
            int len;
            FileInputStream in = new FileInputStream(src);
            while ((len = in.read(buffer)) != -1) {
                zos.write(buffer, 0, len);
            }
            zos.flush();
            zos.closeEntry();
            ClosableUtil.close(in);
        } else {
            File[] listFiles = src.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                if (keepDirStructure) {
                    zos.putNextEntry(new ZipEntry(name + File.separator));
                    zos.closeEntry();
                }

            } else {
                for (File file : listFiles) {
                    if (keepDirStructure) {
                        compress(file, zos, name + File.separator + file.getName(), keepDirStructure);
                    } else
                        compress(file, zos, file.getName(), keepDirStructure);
                }
            }
        }
    }
}
